﻿#include "LogicSystem.h"
#include <csignal>
#include <thread>
#include <mutex>
#include "AsioIOServicePool.h"
#include "CServer.h"
#include "ConfigMgr.h"
#include "RedisMgr.h"
#include "ChatServiceImpl.h"
using namespace std;
bool bstop = false;
std::condition_variable cond_quit;
std::mutex mutex_quit;

// 主函数，程序的入口点
int main()
{
    // 获取配置管理器的单例对象的引用
    auto& cfg = ConfigMgr::Inst();
    auto server_name = cfg["SelfServer"]["Name"];
    try {
        // 获取Asio I/O服务池的单例对象
        auto pool = AsioIOServicePool::GetInstance();

        //将登录数设置为0
        RedisMgr::GetInstance()->HSet(LOGIN_COUNT, server_name, "0");

        //定义一个GrpcServer
        std::string server_address(cfg["SelfServer"]["Host"] + ":" + cfg["SelfServer"]["RPCPort"]);
        ChatServiceImpl service;
        grpc::ServerBuilder builder;
        // 监听端口和添加服务
        builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
        builder.RegisterService(&service);
        // 构建并启动gRPC服务器
        std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
        std::cout << "RPC Server listening on " << server_address << std::endl;

        //单独启动一个线程处理grpc服务
        std::thread  grpc_server_thread([&server]() {
            server->Wait();
            });


        // 创建一个Asio的I/O上下文对象，用于处理异步操作
        boost::asio::io_context  io_context;
        // 创建一个信号集对象，用于监听SIGINT（通常是Ctrl+C）和SIGTERM（通常是系统发送的终止信号）信号
        boost::asio::signal_set signals(io_context, SIGINT, SIGTERM);
        // 异步等待信号的到来，当接收到信号时，执行lambda表达式中的代码
        signals.async_wait([&io_context, pool](auto, auto) {
            // 停止I/O上下文，停止所有正在进行的异步操作
            io_context.stop();
            // 停止Asio I/O服务池
            pool->Stop();
            });
        // 从配置管理器中获取服务器监听的端口号，存储为字符串类型
        auto port_str = cfg["SelfServer"]["Port"];
        // 创建一个CServer对象，传入I/O上下文和端口号（将端口号字符串转换为整数）
        CServer s(io_context, atoi(port_str.c_str()));
        // 启动I/O上下文的事件循环，开始处理异步操作
        io_context.run();
        RedisMgr::GetInstance()->HDel(LOGIN_COUNT, server_name);//删除登录数
        RedisMgr::GetInstance()->Close();//关闭redis连接
        // 等待gRPC服务器线程结束
        grpc_server_thread.join();
    }
    // 捕获所有标准异常
    catch (std::exception& e) {
        // 将异常信息输出到标准错误流
        std::cerr << "Exception: " << e.what() << endl;
    }

    return 0;
}